/*
* $Id: HousingManagerDialog.cpp 170 2010-10-16 18:07:10Z volok-aleksej@yandex.ru $
*
* Copyright 2009 by Alexey Volokitin
* All rights reserved
*
*/
#include "Common/include.h"
#include "HousingManagerDialog.h"
#include "HousingDialog.h"
#include "Components/Journal/FamilyManager.h"
#include "Components/Journal/HousingManager.h"

union tree_id{
	DWORD_PTR u_id;
	struct{
		unsigned id	: 31;
		unsigned type : 1;
	};
};

CHousingManagerDialog::CHousingManagerDialog(CWnd* pParent)
: CDialog(IDD_HOUSE_MANAGE, pParent), m_nIdInfoHousing(0), m_hSelItem(NULL){}
CHousingManagerDialog::~CHousingManagerDialog(){}

void CHousingManagerDialog::SetButtonsState(){
	m_delH.EnableWindow(m_nIdInfoHousing);
	m_changeH.EnableWindow(m_nIdInfoHousing);
	tree_id id = {0};
	HTREEITEM item = m_treeH.GetSelectedItem();
	if(item)
		id.u_id = m_treeH.GetItemData(item);
	m_delF.EnableWindow(id.type);
	m_addF.EnableWindow(m_listH.GetCurSel() != -1 && id.id);
}

void CHousingManagerDialog::SetHousingInfo(int nId){
	CHousingManager* pManager = IJournalComponent::GetHousingManager();
	m_nIdInfoHousing = nId;
	if(m_nIdInfoHousing){
		CHousingManager::housing hive = pManager->GetHousing(nId);
		SetDlgItemText(IDC_NAMEH, hive.m_strName.c_str());
		SetDlgItemText(IDC_TYPEH, pManager->GetType(Housing::HOUSING, hive.m_typeHousing).c_str());
		SetDlgItemText(IDC_TYPEF, pManager->GetType(Housing::FRAME, hive.m_typeframes).c_str());
	}else{
		SetDlgItemText(IDC_NAMEH, _T(""));
		SetDlgItemText(IDC_TYPEH, _T(""));
		SetDlgItemText(IDC_TYPEF, _T(""));
	}
}

void CHousingManagerDialog::ExpandTree(HTREEITEM& item){
	if(item){
		tree_id id = {0};
		if(item != TVI_ROOT)
			id.u_id = m_treeH.GetItemData(item);
		if(!id.type){
			m_treeH.Expand(item, TVE_EXPAND);
			HTREEITEM hItem = m_treeH.GetChildItem(item);
			ExpandTree(hItem);
			if(hItem)
				item = hItem;
		}
	}
}

void CHousingManagerDialog::CollapseTree(HTREEITEM item, HTREEITEM newItem){
	if(item && item != newItem){
		m_treeH.Expand(item, TVE_COLLAPSE);
		CollapseTree(m_treeH.GetParentItem(item), m_treeH.GetParentItem(newItem));
	}
}

BEGIN_MESSAGE_MAP(CHousingManagerDialog, CDialog)
	ON_COMMAND(IDC_ADD_HOUSE, OnAddHouse)
	ON_COMMAND(IDC_CHANGE_HOUSE, OnChangeHouse)
	ON_COMMAND(IDC_DELETE_HOUSE, OnDeleteHouse)
	ON_COMMAND(IDC_ADDF, OnAddFamily)
	ON_COMMAND(IDC_DELETEF, OnDeleteFamily)
	ON_CONTROL(EN_CHANGE, IDC_NAME_HOUSE, OnChangeName)
	ON_CONTROL(LBN_SELCHANGE, IDC_LIST_HOUSE, OnSelChange)
	ON_NOTIFY(TVN_SELCHANGED, IDC_FAMILY_TREE, OnSelChange)
END_MESSAGE_MAP()

BOOL CHousingManagerDialog::OnInitDialog(){
	BOOL bRes = __super::OnInitDialog();
	SetWindowText(ILanguageManager::GetLanguageManager()->GetString(HOUSE_DIALOG_CAPTION_ID).c_str());
	SetDlgItemText(IDOK, ILanguageManager::GetLanguageManager()->GetString(CLOSED_ID).c_str());
	SetDlgItemText(IDC_HOUSE_INFO, ILanguageManager::GetLanguageManager()->GetString(HOUSING_INFO_ID).c_str());
	SetDlgItemText(IDC_NAMEH_STATIC, ILanguageManager::GetLanguageManager()->GetString(HOUSING_NAME_ID).c_str());
	SetDlgItemText(IDC_TYPEH_STATIC, ILanguageManager::GetLanguageManager()->GetString(HOUSING_TYPE_ID).c_str());
	SetDlgItemText(IDC_TYPEF_STATIC, ILanguageManager::GetLanguageManager()->GetString(TYPE_FRAME_ID).c_str());
	m_addH.SetWindowText(ILanguageManager::GetLanguageManager()->GetString(ADD_ID).c_str());
	m_delH.SetWindowText(ILanguageManager::GetLanguageManager()->GetString(DELETE_ID).c_str());
	m_changeH.SetWindowText(ILanguageManager::GetLanguageManager()->GetString(CHANGE_ID).c_str());
	m_delH.EnableWindow(FALSE);
	m_changeH.EnableWindow(FALSE);
	CHousingManager* pHousingManager = IJournalComponent::GetHousingManager();
	CFamilyManager* pFamilyManager = IJournalComponent::GetFamilyManager();
	std::map<int, CHousingManager::housing> aHousings = pHousingManager->GetFamilyHousings(0);
	for(std::map<int, CHousingManager::housing>::iterator it = aHousings.begin(); it != aHousings.end(); it++){
		int item = m_listH.AddString(it->second.m_strName.c_str());
		m_listH.SetItemData(item, it->first);
	}
	std::map<int, CFamilyManager::point> aPoints = pFamilyManager->GetPoints();
	for(std::map<int, CFamilyManager::point>::iterator it = aPoints.begin(); it != aPoints.end(); it++){
		HTREEITEM item = m_treeH.InsertItem(it->second.m_strName.c_str());
		m_treeH.SetItemData(item, 0);
		std::map<int, CFamilyManager::family> aFamilies = pFamilyManager->GetFamilies(it->first);
		for(std::map<int, CFamilyManager::family>::iterator it1 = aFamilies.begin(); it1 != aFamilies.end(); it1++){
			HTREEITEM item1 = m_treeH.InsertItem(it1->second.m_strName.c_str(), item);
			m_treeH.SetItemData(item1, it1->first);
			aHousings = pHousingManager->GetFamilyHousings(it1->first);
			for(std::map<int, CHousingManager::housing>::iterator it2 = aHousings.begin(); it2 != aHousings.end(); it2++){
				HTREEITEM item2 = m_treeH.InsertItem(it2->second.m_strName.c_str(), item1);
				m_treeH.SetItemData(item2, (it2->first|0x80000000));
				m_aItems.insert(std::make_pair(it2->first, item2));
			}
			m_treeH.SortChildren(item1);
		}
		m_treeH.SortChildren(item);
	}
	m_treeH.SortChildren(TVI_ROOT);
	HTREEITEM item = TVI_ROOT;
	ExpandTree(item);
	m_hSelItem = item;
	if(m_hSelItem && m_hSelItem != TVI_ROOT)
		m_treeH.SelectItem(m_hSelItem);
	SetButtonsState();
	return bRes;
}

void CHousingManagerDialog::DoDataExchange(CDataExchange* pDX){
	__super::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_ADD_HOUSE, m_addH);
	DDX_Control(pDX, IDC_DELETE_HOUSE, m_delH);
	DDX_Control(pDX, IDC_CHANGE_HOUSE, m_changeH);
	DDX_Control(pDX, IDC_LIST_HOUSE, m_listH);
	DDX_Control(pDX, IDC_NAME_HOUSE, m_nameH);
	DDX_Control(pDX, IDC_ADDF, m_addF);
	DDX_Control(pDX, IDC_DELETEF, m_delF);
	DDX_Control(pDX, IDC_FAMILY_TREE, m_treeH);
}

void CHousingManagerDialog::OnAddHouse(){
	CHousingDialog dialog;
	if(dialog.DoModal() == IDOK){
		int item = m_listH.AddString(dialog.GetNameHousing().c_str());
		m_listH.SetItemData(item, dialog.GetIdHousing());
		m_listH.SetCurSel(item);
		SetHousingInfo(dialog.GetIdHousing());
		SetButtonsState();
	}
}

void CHousingManagerDialog::OnChangeName(){
	CString strName;
	m_nameH.GetWindowText(strName);
	int item = m_listH.FindString(0, strName);
	if(item >= 0){
		m_listH.SetCurSel(item);
		OnSelChange();
	}
}

void CHousingManagerDialog::OnSelChange(){
	SetHousingInfo((int)m_listH.GetItemData(m_listH.GetCurSel()));
	SetButtonsState();
}

void CHousingManagerDialog::OnSelChange(NMHDR* nmhdr, LRESULT* pResult){
	HTREEITEM item = m_treeH.GetSelectedItem();
	tree_id id = {m_treeH.GetItemData(item)};
	if(m_hSelItem != item){
		if(!id.type){
			ExpandTree(item);
			CollapseTree(m_hSelItem, item);
		};
		m_hSelItem = item;
		m_treeH.SelectItem(item);
	}
	m_listH.SetCurSel(-1);
	id.u_id = m_treeH.GetItemData(m_hSelItem);
	if(id.type)
		SetHousingInfo(id.id);
	else
		SetHousingInfo(0);
	SetButtonsState();
}

void CHousingManagerDialog::OnChangeHouse(){
	CHousingDialog housingDialog(m_nIdInfoHousing);
	std::tstring strName = housingDialog.GetNameHousing();
	if(housingDialog.DoModal() == IDOK){
		SetHousingInfo(m_nIdInfoHousing);
		int item = m_listH.GetCurSel();
		if(item != -1){
			m_listH.DeleteString(item);
			item = m_listH.AddString(housingDialog.GetNameHousing().c_str());
			m_listH.SetItemData(item, housingDialog.GetIdHousing());
			m_listH.SetCurSel(item);
		}
		std::map<int, HTREEITEM>::iterator it = m_aItems.find(m_nIdInfoHousing);
		if(it != m_aItems.end())
			m_treeH.SetItemText(it->second, housingDialog.GetNameHousing().c_str());
	}
}

void CHousingManagerDialog::OnDeleteHouse(){
	std::tstring strContent = ILanguageManager::GetLanguageManager()->GetString(QUESTION_DELETE_ID) +
		_T(" '") + IJournalComponent::GetHousingManager()->GetHousing(m_nIdInfoHousing).m_strName + _T("'.");
	if(MessageBox(strContent.c_str(), ILanguageManager::GetLanguageManager()->
		GetString(DELETE_HOUSING_ID).c_str(), MB_YESNO) == IDYES){
			CHousingManager* pManager = IJournalComponent::GetHousingManager();
			std::tstring strName = pManager->GetHousing(m_nIdInfoHousing).m_strName;
			IJournalComponent::GetHousingManager()->DeleteHousing(m_nIdInfoHousing);
			int item = m_listH.GetCurSel();
			if(item != -1)
				m_listH.DeleteString(item);
			std::map<int, HTREEITEM>::iterator it = m_aItems.find(m_nIdInfoHousing);
			if(it != m_aItems.end()){
				m_treeH.DeleteItem(it->second);
				m_aItems.erase(it);
			}
			SetHousingInfo(0);
	}
	SetButtonsState();
}

void CHousingManagerDialog::OnAddFamily(){
	int nItem = m_listH.GetCurSel();
	int nId = (int)m_listH.GetItemData(nItem);
	CString strName;
	m_listH.GetText(nItem, strName);
	HTREEITEM hItem = m_treeH.GetSelectedItem();
	HTREEITEM hInsertItem = NULL;
	int nIdFamily = 0;
	tree_id id = {m_treeH.GetItemData(hItem)};
	if(id.type){
		nIdFamily = IJournalComponent::GetHousingManager()->GetHousing(id.id).m_nIdFamily;
		hInsertItem = m_treeH.GetParentItem(hItem);
	}else{
		nIdFamily = id.id;
		hInsertItem = hItem;
	}
	IJournalComponent::GetHousingManager()->SetFamily(nId, nIdFamily);
	m_listH.DeleteString(nItem);
	hItem = m_treeH.InsertItem(strName, hInsertItem);
	m_treeH.SetItemData(hItem, nId|0x80000000);
	m_treeH.SelectItem(hItem);
	m_treeH.SetFocus();
	m_aItems.insert(std::make_pair(nId, hItem));
}

void CHousingManagerDialog::OnDeleteFamily(){
	HTREEITEM hItem = m_treeH.GetSelectedItem();
	tree_id id = {m_treeH.GetItemData(hItem)};
	CString strName = m_treeH.GetItemText(hItem);
	IJournalComponent::GetHousingManager()->SetFamily(id.id, 0);
	HTREEITEM ParentItem = m_treeH.GetParentItem(hItem);
	m_treeH.DeleteItem(hItem);
	m_aItems.erase(id.id);
	m_treeH.SelectItem(ParentItem);
	int nItem = m_listH.AddString(strName);
	m_listH.SetItemData(nItem, id.id);
	m_listH.SetCurSel(nItem);
	SetHousingInfo(id.id);
	SetButtonsState();
}
